package br.com.wai2008.socket.direction;

import br.com.wai2008.socket.constants.DirectionConstants;
import comum.Localizacao;

public class Direction {
	
	public void setDirection(Localizacao[] newRoute, Localizacao[] oldRoute, String language) {
		if (oldRoute == null || oldRoute.length == 0) { // nova rota
			if (newRoute != null && newRoute.length <= 2) { //rota nova com menos de dois pontos
				if (newRoute.length == 1) { // rota nova no final
					newRoute[0].setDirection(this.getDirection(DirectionConstants.FINAL, language));
				} else { // rota nova sem estar no final
					int xini = newRoute[0].getX();
					int yini = newRoute[0].getY();
					int xend = newRoute[1].getX();
					int yend = newRoute[1].getY();
					if ((xini-xend) == 0 && (yini-yend) != 0) { // rota nova com deslocamento em x
						newRoute[0].setDirection(this.getDirection(DirectionConstants.SIGUIR_EM_FRENTE, language));
					} else if ((xini-xend) != 0 && (yini-yend) == 0) { // rota nova com deslocamento em y
						newRoute[0].setDirection(this.getDirection(DirectionConstants.SIGUIR_EM_FRENTE, language));
					} else { // rota nova no ultimo nó
						newRoute[0].setDirection(this.getDirection(DirectionConstants.FINAL, language));
					}
				}
				return;
			} else if (newRoute != null && newRoute.length > 2) { //rota nova com mais de dois pontos
				newRoute[0].setDirection(this.getDirection(DirectionConstants.SIGUIR_EM_FRENTE, language));
				return;
			}
		} else {
			// recupera o nó anterior
			int lastX = -1;
			int lastY = -1;
			if (oldRoute.length == 1) {
				lastX = oldRoute[0].getX();
				lastY = oldRoute[0].getY();
			} else {
				if (isNode(oldRoute[0].getX(), oldRoute[0].getY())) {
					lastX = oldRoute[0].getX();
					lastY = oldRoute[0].getY();
				} else {
					lastX = oldRoute[1].getX();
					lastY = oldRoute[1].getY();
				}
			}
			
			// recupera o nó atual e o próximo nó
			int actualX = -1;
			int actualY = -1;
			int nextX = -1;
			int nextY = -1;
			if (newRoute.length == 1) {
				newRoute[0].setDirection(this.getDirection(DirectionConstants.FINAL, language));
				return;
			} else {
				if (isNode(newRoute[0].getX(), newRoute[0].getY())) {
					actualX = newRoute[0].getX();
					actualY = newRoute[0].getY();
					nextX = newRoute[1].getX();
					nextY = newRoute[1].getY();
				} else {
					if (newRoute.length == 2) {
						newRoute[0].setDirection(this.getDirection(DirectionConstants.FINAL, language));
						return;
					} else {
						actualX = newRoute[1].getX();
						actualY = newRoute[1].getY();
						nextX = newRoute[2].getX();
						nextY = newRoute[2].getY();
					}
				}
			}
			
			// verifica para onde deve ir
			if ((lastX-nextX) == 0 || (lastY-nextY) == 0) { // frente ou tras
				System.out.println("LASTX: " + lastX + "   NEXTX: " + nextX + "   LASTY: " + lastY + "   NEXTY: " + nextY);
				if ((lastX-nextX) == 0) {
					if (lastY == nextY) {
						System.out.println("VOLTAR");
						newRoute[0].setDirection(this.getDirection(DirectionConstants.VOLTAR, language));
					} else {
						System.out.println("FRENTE");
						newRoute[0].setDirection(this.getDirection(DirectionConstants.SIGUIR_EM_FRENTE, language));
					}
				} else {
					if (lastX == nextX) {
						System.out.println("VOLTAR");
						newRoute[0].setDirection(this.getDirection(DirectionConstants.VOLTAR, language));
					} else {
						System.out.println("FRENTE");
						newRoute[0].setDirection(this.getDirection(DirectionConstants.SIGUIR_EM_FRENTE, language));
					}
				}
			} else { // mudanca de direção
				if (lastX == actualX) {
					if (actualY == nextY) { // mudou
						if (actualX < nextX && lastY < actualY) {
							newRoute[0].setDirection(this.getDirection(DirectionConstants.VIRAR_ESQUERDA, language));
						} else if (actualX < nextX && lastY > actualY) {
							newRoute[0].setDirection(this.getDirection(DirectionConstants.VIRAR_DIREITA, language));
						} else if (actualX > nextX && lastY < actualY) {
							newRoute[0].setDirection(this.getDirection(DirectionConstants.VIRAR_DIREITA, language));
						} else if (actualX > nextX && lastY > actualY) {
							newRoute[0].setDirection(this.getDirection(DirectionConstants.VIRAR_ESQUERDA, language));
						}
					}
				} else if (lastY == actualY) {
					if (actualX == nextX) { // mudou
						if (actualY < nextY && lastX < actualX) {
							newRoute[0].setDirection(this.getDirection(DirectionConstants.VIRAR_DIREITA, language));
						} else if (actualY < nextY && lastX > actualX){
							newRoute[0].setDirection(this.getDirection(DirectionConstants.VIRAR_ESQUERDA, language));
						} else if (actualY > nextY && lastX < actualX) {
							newRoute[0].setDirection(this.getDirection(DirectionConstants.VIRAR_ESQUERDA, language));
						} else if (actualY > nextY && lastX > actualX){
							newRoute[0].setDirection(this.getDirection(DirectionConstants.VIRAR_DIREITA, language));
						}
					}
				}
			}
		}
	}
	
	private boolean isNode(int x, int y) {
		try {
			return new DirectionDAO().isNode(""+x, ""+y);
		} catch (Exception e) {
			return false;
		}
	}
	
	private String getDirection(int id, String language) {
		try {
			return new DirectionDAO().getDirection(id, language);
		} catch (Exception e) {
			return null;
		}
	}
}
